<?php

/*
 * /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 * php_Util library
 *
 * This library provides some methods that provides extra facilities to php 
 *
 * - php_Util (contains static methods)
 *
 * version 0.44b
 *
 * author: Felipe (felipe.camacho@gmail.com)
 *
 * \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
 */
namespace php_Util;


/**
 * Provides php utilities
 * @author fcamacho
 * @version 0.43
 */
class php_Util {

	/**
	 * DateTime::date_parse_from_format PHP4 compatible
	 *
	 * @tutorial http://uk.php.net/manual/en/function.date-parse-from-format.php
	 *
	 * @param string $format
	 * @param string $date
	 * @return array
	 */

	public static final function date_parse_from_format($format, $date) {
		$dMask = array(
		    'H'=>'hour',
		    'i'=>'minute',
		    's'=>'second',
		    'y'=>'year',
		    'm'=>'month',
		    'd'=>'day'
		);

		$format = preg_split('//', $format, -1, PREG_SPLIT_NO_EMPTY);
		$date = preg_split('//', $date, -1, PREG_SPLIT_NO_EMPTY);
		foreach ($date as $k => $v) {
			if ($dMask[$format[$k]]) $dt[$dMask[$format[$k]]] .= $v;
		}
		return $dt;
	}

	/**
	 * Returns TimeStamp generated using mysql datetime passed as parameter
	 * @param string $mysql_DateTime
	 * @return long
	 */
	public static final function convert_MySQL_DateTime_To_Timestamp($mysql_DateTime) {

		/*
		 * Mysql datetime format: 2011-08-01 10:19:02
		*/

		$array_Date = php_Util::date_parse_from_format('yyyy-mm-dd HH:ii:ss', $mysql_DateTime);
		$timesTamp = mktime($array_Date['hour'],
		$array_Date['minute'],
		$array_Date['second'],
		$array_Date['month'],
		$array_Date['day'],
		$array_Date['year']);
		return $timesTamp;
	}



	/**
	 * Quote variable to make safe
	 * Simple way to prevent SQL injection
	 *
	 * @tutorial http://simon.net.nz/articles/protecting-mysql-sql-injection-attacks-using-php/
	 * @param unknown_type $value
	 * @param int $DB [optional] link to active DB
	 * @return mysql clean variable
	 */
	public static function SQL_Injection_quote_smart($value, $DB = null){
		// Stripslashes
		if ( get_magic_quotes_gpc() ){
			$value = stripslashes( $value );
		}


		// Quote if not a number or a numeric string

		/* I edited this area because I didnâ€™t want this
		 function to automatically place single quotes for
		me since I have done a lot of queries and I would have
		to re do them all.
		Replace with:
		if(!is_numeric($value){
		$value = â€œâ€˜â€�.mysql_real_escape_string($value, $DB).â€�â€˜â€�;
		}
		if you prefer it.
		*/

		$value = mysql_real_escape_string($value, $DB);

		return $value;
	}


	/**
	 *
	 * Return an associtive array with SQL clean variables
	 * @param array $array
	 * @param int $DB [optional] link to active DB
	 * @return array
	 */
	public static function SQL_Injection_getCleanAssocArray($array, $DB = null) {


		// 		foreach (array_keys($_POST) as $var) {
		// 			${$var} = php_Util::SQL_Injection_quote_smart((${$var}));
		// 		}

		if (!is_array($array)) {
			throw new \Exception("Variable isn't array type");
		}

		$myArray = array();
		foreach ($array as $key => $value ){
			$myArray[$key] = php_Util::SQL_Injection_quote_smart($value, $DB);
		}


		return $myArray;
	}


	/**
	 * Append associative array elements
	 * @param multiple $arr -> destination array, array['key'] to insert
	 */
	public static function array_push_associative(&$arr) {
		$args = func_get_args();
		array_unshift($args); // remove &$arr argument
		foreach ($args as $arg) {
			if (is_array($arg)) {
				foreach ($arg as $key => $value) {
					$arr[$key] = $value;
					$ret++;
				}
			}
		}

		return $ret;
	}


	/**
	 * Rounds to up float number
	 * @param float $floatNumber
	 * @param integer $precision
	 * @return float
	 */
	public static function round_To_Up($floatNumber, $precision) {

		$max = round($floatNumber, $precision + 1);
		$min = round($floatNumber, $precision);

		if ($max - $min > 0) {
			$result = $min + pow (10, -$precision);
		} else {
			$result = $min;
		}

		return $result;
	}




	/**
	 * Send asynchronous HTTP Post
	 * @param string $url
	 * @param integer $timeout [optional] default 5
	 * @tutorial http://w-shadow.com/blog/2007/10/16/how-to-run-a-php-script-in-the-background/
	 * @example backgroundPost('http://example.com/slow.php?file='urlencode('some file.dat'));
	 */
	public static function backgroundPost($url, $timeout = 5){
		$parts=parse_url($url);

		$fp = fsockopen($parts['host'],
		isset($parts['port'])?$parts['port']:80,
		$errno, $errstr, $timeout);

		if (!$fp) {
			return false;
		} else {
			$out = "POST ".$parts['path']." HTTP/1.1\r\n";
			$out.= "Host: ".$parts['host']."\r\n";
			$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
			$out.= "Content-Length: ".strlen($parts['query'])."\r\n";
			$out.= "Connection: Close\r\n\r\n";
			if (isset($parts['query'])) $out.= $parts['query'];

			fwrite($fp, $out);
			fclose($fp);
			return true;
		}
	}


	/**
	 * Send asynchronous HTTP Post
	 * @param string $url
	 * @param Array $params
	 * @param integer $timeout [optional] default 5
	 * @tutorial http://petewarden.typepad.com/searchbrowser/2008/06/how-to-post-an.html
	 */
	public static function curl_post_async($url, $params, $timeout = 5) {

		foreach ($params as $key => &$val) {
			if (is_array($val)) $val = implode(',', $val);
			$post_params[] = $key.'='.urlencode($val);
		}

		$post_string = implode('&', $post_params);

		$parts=parse_url($url);

		$fp = fsockopen($parts['host'],
		isset($parts['port'])?$parts['port']:80,
		$errno, $errstr, $timeout);

		if (!$fp) {
			return false;
		} else {
			$out = "POST ".$parts['path']." HTTP/1.1\r\n";
			$out.= "Host: ".$parts['host']."\r\n";
			$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
			$out.= "Content-Length: ".strlen($post_string)."\r\n";
			$out.= "Connection: Close\r\n\r\n";
			if (isset($post_string)) $out.= $post_string;

			fwrite($fp, $out);
			fclose($fp);
		}

	}


	/**
	 * A simple way to check for equality of two floating point numbers. Change the default precision according to your needs
	 *
	 * @param float $x
	 * @param float $y
	 * @param float $precision [optional] default 0.0000001
	 *
	 * @see http://php.net/manual/en/language.types.float.php
	 *
	 */
	public static function IsFloatEqual($x,$y,$precision=0.0000001)
	{
		return ($x+$precision >= $y) && ($x-$precision <= $y);
	}


	/**
	 * Compares two float number with decimal precision passed by parameter
	 * @param float $x
	 * @param float $y
	 * @param integer $decimals
	 * @return boolean
	 *
	 */
	public static function IsFloatEqual_String($x,$y, $decimals)
	{

		$float_A = number_format(floatval($x), $decimals, ".", ",");
		$float_B = number_format(floatval($y), $decimals, ".", ",");

		$result = false;

		error_log($float_A ." ". $float_B);

		if (strcmp($float_A, $float_B) == 0) {
			return true;
		}

		unset($float_A);
		unset($float_B);

		return $result;
	}


	///////////////////////////////////////////////////////
	//DistÃ ncia entre 2 coordenades en Km
	//////////////////////////////////////////////////////
	/**
	*
	* Enter description here ...
	* @param float $lat1 latitude origin
	* @param float $lng1 longitude origin
	* @param float $lat2 latitude destination
	* @param float $lng2 longitude destination
	* @param boolean $miles
	* @return float distance
	*/
	public static function get_Geodistance($lat1, $lng1, $lat2, $lng2, $miles = false) {

		$pi80 = M_PI / 180;
		$lat1 *= $pi80;
		$lng1 *= $pi80;
		$lat2 *= $pi80;
		$lng2 *= $pi80;
		$r = 6372.797; // mean radius of Earth in km

		$dlat = $lat2 - $lat1;
		$dlng = $lng2 - $lng1;
		$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
		$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
		$km = $r * $c;

		return ($miles ? ($km * 0.621371192) : $km);
	}


	/**
	 * Push array into array
	 * @param unknown_type $array_Origin
	 * @param unknown_type $array_toInsert
	 * @return array
	 */
	public static function array_Push_Array($array_Origin, $array_toInsert) {

		$array_Result = array();

		foreach ($array_Origin as $value) {
			array_push($array_Result, $value);
		}

		foreach ($array_toInsert as $value) {
			array_push($array_Result, $value);
		}

		return $array_Result;
	}


	/**
	 * Clean HTML passed as parameter. Remove "\r\n", "\n", "\r", "\t".
	 * @param string $html
	 * @return string
	 */
	public static function clean_HTML_ForFacebox($html) {

		$order   = array("\r\n", "\n", "\r", "\t");
		$replace = '';
		$html_Facebox = str_replace($order, $replace, $html);

		return $html_Facebox;

	}

	
	/**
	 * Return content with specialchars and entities formated in HTML 
	 * @param string $content
	 * @return string
	 */
	public static function get_HTML($content){
		
		$htmlContent = htmlspecialchars($content);
		$htmlContent = htmlentities($htmlContent, null, 'utf-8');

		return $htmlContent;
	}
	
	/**
	 * Simple select MySQL query
	 * @param array $select Select fields into key-value pair array or string
	 * @param string $tablename
	 * @param array $conditions conditions into key-pay pair array or string
	 * @param string $order
	 * @param integer $db_Link [optional] MySQL database link identifier
	 * @return MySQL resulset 
	 * @throws Exception
	 */
	public static function DB_EXEC_QUERY_SELECT($select, $tablename, $conditions = null, $order = null, $db_Link = null) {
		
		// **************************************************************************************************************
		// Check required parameters
		// **************************************************************************************************************
		if ($select == null ||
			$tablename == null) {
			throw new \Exception("Select and tablename required.");
		}
		
		
		// **************************************************************************************************************
		// Set mySQL DB link
		// **************************************************************************************************************
		if ($db_Link == null) {
			$db_Link = mysql_connect();
		}
		
		// **************************************************************************************************************
		// Prepare select part of SQL query
		// **************************************************************************************************************
		$query_select = null;

		if (is_array($select) && sizeof($select) > 0) {
				
			
			$query_select = '';
			foreach ($select as $select_value) {
					
				if ($query_select != '') {
					$query_select .= ", ";
				}
				$query_select .= $select_value;
			}

		} elseif ($select != null && !is_array($select)) {
			$query_select = $select;
		}
		
		
		
		// **************************************************************************************************************
		// Prepare conditions part of SQL query
		// **************************************************************************************************************
		$query_conditions = null;
		if (is_array($conditions) && sizeof($conditions) > 0) {

			$query_conditions = '';
			
			foreach ($conditions as $condition_key => $condition_value) {
				
				if ($query_conditions != '') {
					$query_conditions .= " AND ";
				}
				$query_conditions .= "`$condition_key` = '$condition_value'";
			}

		} elseif ($conditions != null) {
			$query_conditions = $conditions;
		}
		
		
		
		// **************************************************************************************************************
		// Prepare SQL query
		// **************************************************************************************************************
		$sql_Query = "SELECT $query_select FROM $tablename";
		
		
		if ($query_conditions != null){
			$sql_Query .= " WHERE $query_conditions";
		}
		
		
		if ($order != null) {
			$sql_Query .= " ORDER BY $order";
		}
		
		
		
		// **************************************************************************************************************
		// Exec SQL query
		// **************************************************************************************************************
		if (!$sql_Resource = mysql_query($sql_Query, $db_Link)) {
			throw new \Exception("Error Mysql.". mysql_error());
		}
		
		// **************************************************************************************************************
		// If no rows return false else return resultset.
		// **************************************************************************************************************
		if (mysql_num_rows($sql_Resource, $db_Link) == 0) {
			
			mysql_free_result($sql_Resource);
			return false;	
		} else {
			return $sql_Resource;
		}
		
		
	}
	
	
	
	/**
	 * Simple MySQL insert query
	 * @param string $tablename
	 * @param array $insertFields insert fields into key-value pairs array.
	 * @param ingeter $db_Link [optional] MySQL database link identifier  
	 * @return boolean Returns true if insert query is OK.
	 * @throws Exception
	 */
	public static function DB_EXEC_QUERY_INSERT($tablename, $insertFields, $db_Link = null) {
		
		// **************************************************************************************************************
		// Check required parameters
		// **************************************************************************************************************
		if (!is_array($insertFields) || sizeof($insertFields) == 0 || $tablename == null) {
			throw new \Exception("Insert fields and tablename required.");
		}
		
		
		// **************************************************************************************************************
		// Set mySQL DB link
		// **************************************************************************************************************
		if ($db_Link == null) {
			$db_Link = mysql_connect();
		}
		
		
		// **************************************************************************************************************
		// Prepare fields and values part of SQL query
		// **************************************************************************************************************
		$query_fields = '(';
		$query_values = '(';
		
		foreach ($insertFields as $insert_Field_key => $insert_Field_value) {
			
			if ($query_select != '(') {
				$query_select .= ", ";
			}
			$query_fields .= "`$insert_Field_key`";
			
			if ($query_values != '(') {
				$query_values .= ", ";
			}
			$query_values .= "'$insert_Field_value'";
		}
		
		$query_fields .= ')';
		$query_values .= ')';
		
		$sql_Query = "INSERT INTO $tablename $query_fields VALUES $query_values";
		
		
		// **************************************************************************************************************
		// Exec SQL query
		// **************************************************************************************************************
		if (!$mysql_Resource = mysql_query($sql_Query, $db_Link)) {
			throw new \Exception("Error Mysql. ". mysql_error()); 
		}
		
		// **************************************************************************************************************
		// Free memory and return result
		// **************************************************************************************************************
		$num_Rows = mysql_affected_rows($db_Link);
		mysql_free_result($mysql_Resource);
		
		return $num_Rows;
	}
	
	/**
	 * Simple MySQL update query
	 * @param string $tablename
	 * @param array $updateFields values to update into key-value pair array. 
	 * @param array $conditions conditions into key-value pair array or string.
	 * @param integer $db_Link [optional] MySQL database link identifier
	 * @return Mysql resulset
	 * @throws Exception
	 */
	public static function DB_EXEC_QUERY_UPDATE($tablename, $updateFields, $conditions = null, $db_Link = null) {
		
		// **************************************************************************************************************
		// Check required parameters
		// **************************************************************************************************************
		if (!is_array($updateFields) || sizeof($updateFields) == 0 || $tablename == null) {
			throw new \Exception("Update fields and tablename required");
		}
		
		// **************************************************************************************************************
		// Set mySQL DB link
		// **************************************************************************************************************
		if ($db_Link == null) {
			$db_Link = mysql_connect();
		}
		
		mysql_thread_id();
		
		// **************************************************************************************************************
		// Prepare fields and values part of SQL query
		// **************************************************************************************************************
		$query_update_Fields = '';
		
		foreach ($updateFields as $update_Field_key => $update_Field_value) {
			
			if ($query_update_Fields != '') {
				$query_update_Fields .= ', ';	
			}
			
			$query_update_Fields .= "`$update_Field_key` = '$update_Field_value'";
		}
		
		// **************************************************************************************************************
		// Prepare conditions part of SQL query
		// **************************************************************************************************************
		$query_conditions = null;
		if (is_array($conditions) && sizeof($conditions) > 0) {
			
			$query_conditions = '';
			
			foreach ($conditions as $condition_key => $condition_value) {
				
				if ($query_conditions != '') {
					$query_conditions .= ' AND ';
				}
				
				$query_conditions .= "`$condition_key` = '$condition_value'";
			}
			
			
			
		} elseif ($conditions != null) {
			$query_conditions = $conditions;
		}
		
		// **************************************************************************************************************
		// Build SQL query
		// **************************************************************************************************************
		$sql_Query = "UPDATE $tablename SET $updateFields";
		if ($query_conditions) {
			$sql_Query .= " WHERE $query_conditions";
		}
		
		
		// **************************************************************************************************************
		// Exec SQL query
		// **************************************************************************************************************
		if (!$mysql_Resource = mysql_query($sql_Query, $db_Link)) {
			throw new \Exception("Error Mysql. ". mysql_error()); 
		}
		
		
		// **************************************************************************************************************
		// Free memory and return result
		// **************************************************************************************************************
		$num_rows = mysql_affected_rows($db_Link);
		mysql_free_result($mysql_Resource);

		return $num_rows;
	}
	
	/**
	 * Simple Mysql delete query
	 * @param string $tablename
	 * @param array $conditions Conditions key-value pair array or string
	 * @param integer $db_Link [optional] MySQL database link identifier
	 * @return integer number of affected rows or false if fails
	 * @throws Exception
	 */
	public static function DB_EXEC_QUERY_DELETE($tablename, $conditions, $db_Link = null) {
		
		
		if ($conditions == null || $tablename == null) {
			throw new \Exception("Conditions and tablename required.");
		}
		
		
		// **************************************************************************************************************
		// Set mySQL DB link
		// **************************************************************************************************************
		if ($db_Link == null) {
			$db_Link = mysql_connect();
		}
		
		// **************************************************************************************************************
		// Prepare conditions part of SQL query
		// **************************************************************************************************************
		$query_conditions = null;
		if (is_array($conditions) && sizeof($conditions) > 0) {
				
			$query_conditions = '';
				
			foreach ($conditions as $condition_key => $condition_value) {
		
				if ($query_conditions != '') {
					$query_conditions .= ' AND ';
				}
		
				$query_conditions .= "`$condition_key` = '$condition_value'";
			}
				
				
				
		} elseif ($conditions != null) {
			$query_conditions = $conditions;
		}
		
		// **************************************************************************************************************
		// Build SQL query
		// **************************************************************************************************************
		$sql_Query = "DELETE FROM `$tablename`";
		if ($query_conditions) {
			$sql_Query .= " WHERE $query_conditions";
		}
		
		// **************************************************************************************************************
		// Exec SQL query
		// **************************************************************************************************************
		if (!$mysql_Resource =  mysql_query($sql_Query, $db_Link)) {
			throw new \Exception("Error Mysql. ". mysql_error());
		}
		
		
		// **************************************************************************************************************
		// Free memory and return affected rows as result
		// **************************************************************************************************************
		$num_rows = mysql_affected_rows($db_Link);
		unset($mysql_Resource);
		
		return $num_rows;
	}
	
	
	
	
	public static function charset_decode_utf_8 ($string) {
		/* Only do the slow convert if there are 8-bit characters */
		/* avoid using 0xA0 (\240) in ereg ranges. RH73 does not like that */
		if (! ereg("[\200-\237]", $string) and ! ereg("[\241-\377]", $string))
		return $string;
	
		// decode three byte unicode characters
		$string = preg_replace("/([\340-\357])([\200-\277])([\200-\277])/e",
	    "'&#'.((ord('\\1')-224)*4096 + (ord('\\2')-128)*64 + (ord('\\3')-128)).';'",    
		$string);
	
		// decode two byte unicode characters
		$string = preg_replace("/([\300-\337])([\200-\277])/e",
	    "'&#'.((ord('\\1')-192)*64+(ord('\\2')-128)).';'", 
		$string);
	
		return $string;
	}
	
	
	
	
	/**
	 * 
	 * @param int $length
	 * @param string $possible
	 */
	public static function generatePassword ($length = 8, $possible = null) {
	
		// start with a blank password
		$password = "";
	
		// define possible characters - any character in this string can be
		// picked for use in the password, so if you want to put vowels back in
		// or add special characters such as exclamation marks, this is where
		// you should do it
		if ($possible == null) {
			$possible = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
		}
		
	
		// we refer to the length of $possible a few times, so let's grab it now
		$maxlength = strlen($possible);
	
		// check for length overflow and truncate if necessary
		if ($length > $maxlength) {
			$length = $maxlength;
		}
	
		// set up a counter for how many characters are in the password so far
		$i = 0;
	
		// add random characters to $password until $length is reached
		while ($i < $length) {
	
			// pick a random character from the possible ones
			$char = substr($possible, mt_rand(0, $maxlength-1), 1);
	
			// have we already used this character in $password?
			if (!strstr($password, $char)) {
				// no, so it's OK to add it onto the end of whatever we've already got...
				$password .= $char;
				// ... and increase the counter by one
				$i++;
			}
	
		}
	
		// done!
		return $password;
	
	}

	
	/**
	 * Count character ocurrences
	 * @param string $char_string String to search
	 * @param string $haystack 
	 * @param boolean $case_sensitive
	 * @tutorial http://stackoverflow.com/questions/4736058/php-count-of-occurrences-of-characters-of-a-string-within-another-string
	 * @return integer
	 */
	public static function count_occurences($char_string, $haystack, $case_sensitive = true){
		if($case_sensitive === false){
			$char_string = strtolower($char_string);
			$haystack = strtolower($haystack);
		}
	
		$characters = str_split($char_string);
		$character_count = 0;
		foreach($characters as $character){
			$character_count = $character_count + substr_count($haystack, $character);
		}
		return $character_count;
	}
	
	/**
	 * Truncate sentence adding '...'
	 * 
	 * @param $str string to truncate
	 * @param $length max lenght of result
	 * @tutorial http://stackoverflow.com/questions/4474517/shortening-a-string-with-on-the-end
	 * @return string
	 */
	public static function str_truncate($str, $length) {
		if(strlen($str) <= $length) return $str;
		return substr($str, 0, $length - 3) . '...';
	}
	
	
	
	/**
	 * Method that runs json decode using magic quotes condition.
	 * 
	 * @tutorial http://blog.thefrontiergroup.com.au/2008/11/json_decode_php/
	 *  
	 * @param unknown $string
	 * @return mixed
	 */
	public static function _json_decode($string) {
		if (get_magic_quotes_gpc()) {
			$string = stripslashes($string);
		}
	
		return json_decode($string);
	}
	
	
	
}



